/************************************************************************/
/* gaoxinglong @xspeech                                                 */
/************************************************************************/
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>
#include <set>
#include <exception>
#include <sstream>
#include <thread>
#include "string_manager.h"


#ifdef _MSC_VER

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
using namespace boost::algorithm;
#include <boost/regex.hpp>
#else
#include <unistd.h>
#endif


bool CheckFile(const char* file_access_dir){
	if (!file_access_dir)
		return false;
#ifdef _MSC_VER
	using namespace boost::filesystem;
	namespace bf = boost::filesystem;
	bf::path access_dir = file_access_dir;
	if (!bf::exists(access_dir))
		return false;
	return true;
#else
	if (access(file_access_dir, 4) < 0)
	{
		return false;
	}
	return true;
#endif

}




StringManager::StringManager()
{
	mString = "";
}

StringManager::~StringManager()
{
}


StringManager::StringManager(const char* str)
{
	if (str)
		mString = str;
}

StringManager::StringManager(const string& str)
{
	if (! str.empty()){
		mString = str;
	}
}


int StringManager::SplitStringtoSpecializedSize(const char* original_string, const char* delimiter, vector<string>* results, int split_times){
	if (!original_string || !delimiter || !results){
		return -1;
	}
	string ori_str = preprocess_string(original_string);
	string deli_str = delimiter, part_str = "";
	vector<string> delis;
	string::size_type sub_str_start = 0, sub_str_end = FindSpecialPos(ori_str.c_str(), deli_str.c_str());
	while (sub_str_end != string::npos)
	{
		results->push_back(ori_str.substr(sub_str_start, sub_str_end - sub_str_start));
		part_str = ori_str.substr(sub_str_end + 1);
		if (results->size() == split_times)
		{
			results->push_back(part_str);
			break;
		}
		sub_str_start = sub_str_end;
		sub_str_end = FindSpecialPos(part_str.c_str(), deli_str.c_str());

	}
	if (results->size()){
		return results->size();
	}
	return -1;
}


string  StringManager::ConvertWhite2SingleBlank(const char* original_string){
	string temp_string = original_string, final_string, next_token;
	if (temp_string.empty())
	{
		return temp_string;
	}
	istringstream temp_stream(temp_string);
	while (!temp_stream.eof())
	{
		temp_stream >> next_token;
		if (next_token != " " || next_token != "\t")
		{
			final_string = final_string + next_token;
			if (temp_stream.eof()){
				break;
			}
			else{
				final_string += " ";
			}
		}
	}

	return final_string;
}


string StringManager::preprocess_string(const char* original_string){
	string temp_string = original_string, processed_string;

	if (temp_string.empty())
	{
		return temp_string;
	}
	processed_string = ConvertWhite2SingleBlank(temp_string.c_str());
	if (!processed_string.empty())
		return processed_string;
	return temp_string;
}


int StringManager::FindSpecialPos(const char* original_str, const char* delimiter){
	int pos = -1;
	if (!original_str || !delimiter){
		return pos;
	}
	string deli_array = delimiter, test_str = original_str;
	vector<int> pos_array;
	int i = 0;
	while (i < deli_array.size())
	{
		string::size_type result_pos = test_str.find_first_of(deli_array[i]);
		if (result_pos != string::npos)
		{
			pos_array.push_back(result_pos);
		}
		i++;
	}
	std::vector<int>::iterator min_iter = min_element(pos_array.begin(), pos_array.end());
	if (min_iter != pos_array.end() && (*min_iter) > pos)
	{
		return (*min_iter);
	}
	return pos;
}


StringManager& StringManager::operator=(const StringManager& str)
{
	if (str.get_string() == this->mString){
		return *this;
	}
	set_string(str.get_string());
}
